/***********************************************************************
 * 
 * File: STMCommon/stmblitter.cpp
 * Copyright (c) 2007 STMicroelectronics Limited.
 * 
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
\***********************************************************************/

#include <stmdisplay.h>

#include <Generic/IOS.h>
#include <Generic/IDebug.h>
#include <Generic/DisplayDevice.h>

#include "stmblitter.h"

static const stm_blit_filter_coeffs stm_blitter_8x8_filters[] = 
{
  { 0, 921 , {
    0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x00,  0x00,
    0x00,  0x00,  0xff,  0x07,  0x3d,  0xfc,  0x01,  0x00,
    0x00,  0x01,  0xfd,  0x11,  0x36,  0xf9,  0x02,  0x00,
    0x00,  0x01,  0xfb,  0x1b,  0x2e,  0xf9,  0x02,  0x00,
    0x00,  0x01,  0xf9,  0x26,  0x26,  0xf9,  0x01,  0x00,
    0x00,  0x02,  0xf9,  0x30,  0x19,  0xfb,  0x01,  0x00,
    0x00,  0x02,  0xf9,  0x39,  0x0e,  0xfd,  0x01,  0x00,
    0x00,  0x01,  0xfc,  0x3e,  0x06,  0xff,  0x00,  0x00 }
  },
  { 921, 1024, {
    0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x00,  0x00,
    0xff,  0x03,  0xfd,  0x08,  0x3e,  0xf9,  0x04,  0xfe,
    0xfd,  0x06,  0xf8,  0x13,  0x3b,  0xf4,  0x07,  0xfc,
    0xfb,  0x08,  0xf5,  0x1f,  0x34,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x2b,  0x2a,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x35,  0x1e,  0xf4,  0x08,  0xfb,
    0xfc,  0x07,  0xf5,  0x3c,  0x12,  0xf7,  0x06,  0xfd,
    0xfe,  0x04,  0xfa,  0x3f,  0x07,  0xfc,  0x03,  0xff }
  },
  { 1024, 1126, {
    0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x00,  0x00,
    0xff,  0x03,  0xfd,  0x08,  0x3e,  0xf9,  0x04,  0xfe,
    0xfd,  0x06,  0xf8,  0x13,  0x3b,  0xf4,  0x07,  0xfc,
    0xfb,  0x08,  0xf5,  0x1f,  0x34,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x2b,  0x2a,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x35,  0x1e,  0xf4,  0x08,  0xfb,
    0xfc,  0x07,  0xf5,  0x3c,  0x12,  0xf7,  0x06,  0xfd,
    0xfe,  0x04,  0xfa,  0x3f,  0x07,  0xfc,  0x03,  0xff }
  },
  { 1126, 1228, {
    0x00,  0x00,  0x00,  0x00,  0x40,  0x00,  0x00,  0x00,
    0xff,  0x03,  0xfd,  0x08,  0x3e,  0xf9,  0x04,  0xfe,
    0xfd,  0x06,  0xf8,  0x13,  0x3b,  0xf4,  0x07,  0xfc,
    0xfb,  0x08,  0xf5,  0x1f,  0x34,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x2b,  0x2a,  0xf1,  0x09,  0xfb,
    0xfb,  0x09,  0xf2,  0x35,  0x1e,  0xf4,  0x08,  0xfb,
    0xfc,  0x07,  0xf5,  0x3c,  0x12,  0xf7,  0x06,  0xfd,
    0xfe,  0x04,  0xfa,  0x3f,  0x07,  0xfc,  0x03,  0xff }
  },
  { 1228, 1331, {
    0xfd,  0x04,  0xfc,  0x05,  0x39,  0x05,  0xfc,  0x04,
    0xfc,  0x06,  0xf9,  0x0c,  0x39,  0xfe,  0x00,  0x02,
    0xfb,  0x08,  0xf6,  0x17,  0x35,  0xf9,  0x02,  0x00,
    0xfc,  0x08,  0xf4,  0x20,  0x30,  0xf4,  0x05,  0xff,
    0xfd,  0x07,  0xf4,  0x29,  0x28,  0xf3,  0x07,  0xfd,
    0xff,  0x05,  0xf5,  0x31,  0x1f,  0xf3,  0x08,  0xfc,
    0x00,  0x02,  0xf9,  0x38,  0x14,  0xf6,  0x08,  0xfb,
    0x02,  0x00,  0xff,  0x3a,  0x0b,  0xf8,  0x06,  0xfc }
  },
  { 1331, 1433, {
    0xfc,  0x06,  0xf9,  0x09,  0x34,  0x09,  0xf9,  0x06,
    0xfd,  0x07,  0xf7,  0x10,  0x32,  0x02,  0xfc,  0x05,
    0xfe,  0x07,  0xf6,  0x17,  0x2f,  0xfc,  0xff,  0x04,
    0xff,  0x06,  0xf5,  0x20,  0x2a,  0xf9,  0x01,  0x02,
    0x00,  0x04,  0xf6,  0x27,  0x25,  0xf6,  0x04,  0x00,
    0x02,  0x01,  0xf9,  0x2d,  0x1d,  0xf5,  0x06,  0xff,
    0x04,  0xff,  0xfd,  0x31,  0x15,  0xf5,  0x07,  0xfe,
    0x05,  0xfc,  0x02,  0x35,  0x0d,  0xf7,  0x07,  0xfd }
  },
  { 1433, 1536, {
    0xfe,  0x06,  0xf8,  0x0b,  0x30,  0x0b,  0xf8,  0x06,
    0xff,  0x06,  0xf7,  0x12,  0x2d,  0x05,  0xfa,  0x06,
    0x00,  0x04,  0xf6,  0x18,  0x2c,  0x00,  0xfc,  0x06,
    0x01,  0x02,  0xf7,  0x1f,  0x27,  0xfd,  0xff,  0x04,
    0x03,  0x00,  0xf9,  0x24,  0x24,  0xf9,  0x00,  0x03,
    0x04,  0xff,  0xfd,  0x29,  0x1d,  0xf7,  0x02,  0x01,
    0x06,  0xfc,  0x00,  0x2d,  0x17,  0xf6,  0x04,  0x00,
    0x06,  0xfa,  0x05,  0x30,  0x0f,  0xf7,  0x06,  0xff }
  },
  { 1536, 2048, {
    0x05,  0xfd,  0xfb,  0x13,  0x25,  0x13,  0xfb,  0xfd,
    0x05,  0xfc,  0xfd,  0x17,  0x24,  0x0f,  0xf9,  0xff,
    0x04,  0xfa,  0xff,  0x1b,  0x24,  0x0b,  0xf9,  0x00,
    0x03,  0xf9,  0x01,  0x1f,  0x23,  0x08,  0xf8,  0x01,
    0x02,  0xf9,  0x04,  0x22,  0x20,  0x04,  0xf9,  0x02,
    0x01,  0xf8,  0x08,  0x25,  0x1d,  0x01,  0xf9,  0x03,
    0x00,  0xf9,  0x0c,  0x25,  0x1a,  0xfe,  0xfa,  0x04,
    0xff,  0xf9,  0x10,  0x26,  0x15,  0xfc,  0xfc,  0x05 }
  },
  { 2048, 3072, {
    0xfc,  0xfd,  0x06,  0x13,  0x18,  0x13,  0x06,  0xfd,
    0xfc,  0xfe,  0x08,  0x15,  0x17,  0x12,  0x04,  0xfc,
    0xfb,  0xfe,  0x0a,  0x16,  0x18,  0x10,  0x03,  0xfc,
    0xfb,  0x00,  0x0b,  0x18,  0x17,  0x0f,  0x01,  0xfb,
    0xfb,  0x00,  0x0d,  0x19,  0x17,  0x0d,  0x00,  0xfb,
    0xfb,  0x01,  0x0f,  0x19,  0x16,  0x0b,  0x00,  0xfb,
    0xfc,  0x03,  0x11,  0x19,  0x15,  0x09,  0xfe,  0xfb,
    0xfc,  0x04,  0x12,  0x1a,  0x12,  0x08,  0xfe,  0xfc }
  },
  { 3072, 4096, {
    0xfe,  0x02,  0x09,  0x0f,  0x0e,  0x0f,  0x09,  0x02,
    0xff,  0x02,  0x09,  0x0f,  0x10,  0x0e,  0x08,  0x01,
    0xff,  0x03,  0x0a,  0x10,  0x10,  0x0d,  0x07,  0x00,
    0x00,  0x04,  0x0b,  0x10,  0x0f,  0x0c,  0x06,  0x00,
    0x00,  0x05,  0x0c,  0x10,  0x0e,  0x0c,  0x05,  0x00,
    0x00,  0x06,  0x0c,  0x11,  0x0e,  0x0b,  0x04,  0x00,
    0x00,  0x07,  0x0d,  0x11,  0x0f,  0x0a,  0x03,  0xff,
    0x01,  0x08,  0x0e,  0x11,  0x0e,  0x09,  0x02,  0xff }
  },
  { 4096, 5120, {
    0x00,  0x04,  0x09,  0x0c,  0x0e,  0x0c,  0x09,  0x04,
    0x01,  0x05,  0x09,  0x0c,  0x0d,  0x0c,  0x08,  0x04,
    0x01,  0x05,  0x0a,  0x0c,  0x0e,  0x0b,  0x08,  0x03,
    0x02,  0x06,  0x0a,  0x0d,  0x0c,  0x0b,  0x07,  0x03,
    0x02,  0x07,  0x0a,  0x0d,  0x0d,  0x0a,  0x07,  0x02,
    0x03,  0x07,  0x0b,  0x0d,  0x0c,  0x0a,  0x06,  0x02,
    0x03,  0x08,  0x0b,  0x0d,  0x0d,  0x0a,  0x05,  0x01,
    0x04,  0x08,  0x0c,  0x0d,  0x0c,  0x09,  0x05,  0x01 }
  },
  { 5120, 6144, {
    0x03,  0x06,  0x09,  0x0b,  0x09,  0x0b,  0x09,  0x06,
    0x03,  0x06,  0x09,  0x0b,  0x0c,  0x0a,  0x08,  0x05,
    0x03,  0x06,  0x09,  0x0b,  0x0c,  0x0a,  0x08,  0x05,
    0x04,  0x07,  0x09,  0x0b,  0x0b,  0x0a,  0x08,  0x04,
    0x04,  0x07,  0x0a,  0x0b,  0x0b,  0x0a,  0x07,  0x04,
    0x04,  0x08,  0x0a,  0x0b,  0x0b,  0x09,  0x07,  0x04,
    0x05,  0x08,  0x0a,  0x0b,  0x0c,  0x09,  0x06,  0x03,
    0x05,  0x08,  0x0a,  0x0b,  0x0c,  0x09,  0x06,  0x03 }
  }
};

static const stm_blit_filter_coeffs stm_blitter_5x8_filters[] =
{
  { 0, 921, {
    0x00,  0x00,  0x40,  0x00,  0x00,
    0x00,  0x05,  0x3d,  0xfe,  0x00,
    0x00,  0x0d,  0x36,  0xfd,  0x00,
    0xff,  0x17,  0x2d,  0xfd,  0x00,
    0xfe,  0x23,  0x21,  0xfe,  0x00,
    0xfd,  0x2e,  0x16,  0xff,  0x00,
    0xfd,  0x37,  0x0c,  0x00,  0x00,
    0xfe,  0x3e,  0x04,  0x00,  0x00 }
  },
  { 921, 1024, {
    0x00,  0x00,  0x40,  0x00,  0x00,
    0xfd,  0x09,  0x3c,  0xfa,  0x04,
    0xf9,  0x13,  0x39,  0xf5,  0x06,
    0xf5,  0x1f,  0x31,  0xf3,  0x08,
    0xf3,  0x2a,  0x28,  0xf3,  0x08,
    0xf3,  0x34,  0x1d,  0xf5,  0x07,
    0xf5,  0x3b,  0x12,  0xf9,  0x05,
    0xfa,  0x3f,  0x07,  0xfd,  0x03 }
  },
  { 1024, 1126, {
    0x00,  0x00,  0x40,  0x00,  0x00,
    0xfd,  0x09,  0x3c,  0xfa,  0x04,
    0xf9,  0x13,  0x39,  0xf5,  0x06,
    0xf5,  0x1f,  0x31,  0xf3,  0x08,
    0xf3,  0x2a,  0x28,  0xf3,  0x08,
    0xf3,  0x34,  0x1d,  0xf5,  0x07,
    0xf5,  0x3b,  0x12,  0xf9,  0x05,
    0xfa,  0x3f,  0x07,  0xfd,  0x03 }
  },
  { 1126, 1228, {
    0x00,  0x00,  0x40,  0x00,  0x00,
    0xfd,  0x09,  0x3c,  0xfa,  0x04,
    0xf9,  0x13,  0x39,  0xf5,  0x06,
    0xf5,  0x1f,  0x31,  0xf3,  0x08,
    0xf3,  0x2a,  0x28,  0xf3,  0x08,
    0xf3,  0x34,  0x1d,  0xf5,  0x07,
    0xf5,  0x3b,  0x12,  0xf9,  0x05,
    0xfa,  0x3f,  0x07,  0xfd,  0x03 }
  },
  { 1228, 1331, {
    0xfc,  0x05,  0x3e,  0x05,  0xfc,
    0xf8,  0x0e,  0x3b,  0xff,  0x00,
    0xf5,  0x18,  0x38,  0xf9,  0x02,
    0xf4,  0x21,  0x31,  0xf5,  0x05,
    0xf4,  0x2a,  0x27,  0xf4,  0x07,
    0xf6,  0x30,  0x1e,  0xf4,  0x08,
    0xf9,  0x35,  0x15,  0xf6,  0x07,
    0xff,  0x37,  0x0b,  0xf9,  0x06 }
  },
  { 1331, 1433, {
    0xf8,  0x0a,  0x3c,  0x0a,  0xf8,
    0xf6,  0x12,  0x3b,  0x02,  0xfb,
    0xf4,  0x1b,  0x35,  0xfd,  0xff,
    0xf4,  0x23,  0x30,  0xf8,  0x01,
    0xf6,  0x29,  0x27,  0xf6,  0x04,
    0xf9,  0x2e,  0x1e,  0xf5,  0x06,
    0xfd,  0x31,  0x16,  0xf6,  0x06,
    0x02,  0x32,  0x0d,  0xf8,  0x07 }
  },
  { 1433, 1536, {
    0xf6,  0x0e,  0x38,  0x0e,  0xf6,
    0xf5,  0x15,  0x38,  0x06,  0xf8,
    0xf5,  0x1d,  0x33,  0x00,  0xfb,
    0xf6,  0x23,  0x2d,  0xfc,  0xfe,
    0xf9,  0x28,  0x26,  0xf9,  0x00,
    0xfc,  0x2c,  0x1e,  0xf7,  0x03,
    0x00,  0x2e,  0x18,  0xf6,  0x04,
    0x05,  0x2e,  0x11,  0xf7,  0x05 }
  },
  { 1536, 2048, {
    0xfb,  0x13,  0x24,  0x13,  0xfb,
    0xfd,  0x17,  0x23,  0x0f,  0xfa,
    0xff,  0x1a,  0x23,  0x0b,  0xf9,
    0x01,  0x1d,  0x22,  0x07,  0xf9,
    0x04,  0x20,  0x1f,  0x04,  0xf9,
    0x07,  0x22,  0x1c,  0x01,  0xfa,
    0x0b,  0x24,  0x17,  0xff,  0xfb,
    0x0f,  0x24,  0x14,  0xfd,  0xfc }
  },
  { 2048, 3072, {
    0x05,  0x10,  0x16,  0x10,  0x05,
    0x06,  0x11,  0x16,  0x0f,  0x04,
    0x08,  0x13,  0x15,  0x0e,  0x02,
    0x09,  0x14,  0x16,  0x0c,  0x01,
    0x0b,  0x15,  0x15,  0x0b,  0x00,
    0x0d,  0x16,  0x13,  0x0a,  0x00,
    0x0f,  0x17,  0x13,  0x08,  0xff,
    0x11,  0x18,  0x12,  0x07,  0xfe }
  },
  { 3072, 4096, {
    0x09,  0x0f,  0x10,  0x0f,  0x09,
    0x09,  0x0f,  0x12,  0x0e,  0x08,
    0x0a,  0x10,  0x11,  0x0e,  0x07,
    0x0b,  0x11,  0x11,  0x0d,  0x06,
    0x0c,  0x11,  0x12,  0x0c,  0x05,
    0x0d,  0x12,  0x11,  0x0c,  0x04,
    0x0e,  0x12,  0x11,  0x0b,  0x04,
    0x0f,  0x13,  0x11,  0x0a,  0x03 }
  },
  { 4096, 5120, {
    0x0a,  0x0e,  0x10,  0x0e,  0x0a,
    0x0b,  0x0e,  0x0f,  0x0e,  0x0a,
    0x0b,  0x0f,  0x10,  0x0d,  0x09,
    0x0c,  0x0f,  0x10,  0x0d,  0x08,
    0x0d,  0x0f,  0x0f,  0x0d,  0x08,
    0x0d,  0x10,  0x10,  0x0c,  0x07,
    0x0e,  0x10,  0x0f,  0x0c,  0x07,
    0x0f,  0x10,  0x10,  0x0b,  0x06 }
  },
  { 5120, 6144, {
    0x0b,  0x0e,  0x0e,  0x0e,  0x0b,
    0x0b,  0x0e,  0x0f,  0x0d,  0x0b,
    0x0c,  0x0e,  0x0f,  0x0d,  0x0a,
    0x0c,  0x0e,  0x0f,  0x0d,  0x0a,
    0x0d,  0x0f,  0x0e,  0x0d,  0x09,
    0x0d,  0x0f,  0x0f,  0x0c,  0x09,
    0x0e,  0x0f,  0x0e,  0x0c,  0x09,
    0x0e,  0x0f,  0x0f,  0x0c,  0x08 }
  }
};


static const int STM_NUM_5X8_FILTERS = sizeof(stm_blitter_5x8_filters)/sizeof(stm_blit_filter_coeffs);
static const int STM_NUM_8X8_FILTERS = sizeof(stm_blitter_8x8_filters)/sizeof(stm_blit_filter_coeffs);


const ULONG stm_flicker_filter_coeffs[4] = {
    0x04008000,
    0x06106010,
    0x08185018,
    0x00204020
};

static const ULONG CLUT_SIZE = sizeof(ULONG)*256;


CSTmBlitter::CSTmBlitter(ULONG *pBlitterBaseAddr)
{
  DEBUGF2(2, (FENTRY ": baseAddr = %p\n",__PRETTY_FUNCTION__, pBlitterBaseAddr));  

  m_pBlitterReg       = pBlitterBaseAddr;
  m_ulBufferNodes     = 0;
  m_ulBufferHeadIndex = 0;
  m_ulBufferTailIndex = 0;
  m_nodesWaiting      = 0;
  
  DEXIT();
}


CSTmBlitter::~CSTmBlitter()
{
  DENTRY();  

  g_pIOS->FreeDMAArea(&m_5x8FilterTables);
  g_pIOS->FreeDMAArea(&m_8x8FilterTables);
  
  if(m_preemptionLock)
    g_pIOS->DeleteResourceLock(m_preemptionLock);
     
  m_pBlitterReg = 0;

  DEXIT();  
}


bool CSTmBlitter::Create()
{     
  DENTRY();  

  g_pIOS->AllocateDMAArea(&m_5x8FilterTables, (STM_BLIT_FILTER_TABLE_SIZE*STM_NUM_5X8_FILTERS), 16, SDAAF_NONE);
  if(!m_5x8FilterTables.pMemory)
    return false;
  
  for(int i=0;i<STM_NUM_5X8_FILTERS;i++)
  {
    g_pIOS->MemcpyToDMAArea(&m_5x8FilterTables,
                             (i*STM_BLIT_FILTER_TABLE_SIZE),
                             stm_blitter_5x8_filters[i].filter_coeffs,
                             STM_BLIT_FILTER_TABLE_SIZE*sizeof(UCHAR));
  }
  
  g_pIOS->AllocateDMAArea(&m_8x8FilterTables, (STM_BLIT_FILTER_TABLE_SIZE*STM_NUM_8X8_FILTERS), 16, SDAAF_NONE);
  if(!m_8x8FilterTables.pMemory)
    return false;
  
  for(int i=0;i<STM_NUM_8X8_FILTERS;i++)
  {
    g_pIOS->MemcpyToDMAArea(&m_8x8FilterTables,
                             (i*STM_BLIT_FILTER_TABLE_SIZE),
                             stm_blitter_8x8_filters[i].filter_coeffs,
                             STM_BLIT_FILTER_TABLE_SIZE*sizeof(UCHAR));
  }

  m_preemptionLock = g_pIOS->CreateResourceLock();
  if(!m_preemptionLock)
    return false;

  DEXIT();
  return true;
}


int CSTmBlitter::SyncChip(bool WaitNextOnly)
{
  int err;

  DEBUGF2(3, ("CSTmBlitter::SyncChip() m_nodesWaiting = %lu\n",m_nodesWaiting));

  /*
   * We need to deal with possible signal delivery while sleeping,
   * this is indicated by a non zero return value. The sleep itself is
   * safe from race conditions in testing the state of m_nodesWaiting.
   * In this case we sleep until m_nodesWaiting == 0 .
   */
  if((err = g_pIOS->SleepOnQueue(BLIT_ENGINE_QUEUE,&m_nodesWaiting,0,STMIOS_WAIT_COND_EQUAL)) != 0)
    return err;
    
  return 0;
}


bool CSTmBlitter::SetBufferType(const stm_blitter_surface_t &Surf, ULONG* pReg)
{    
  *pReg = Surf.ulStride;

  /*
   * Note that we don't support any of the YUV formats in the blitter at
   * the moment.
   */
  switch(Surf.format)
  {
    case SURF_ARGB8888:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ARGB8888\n"));
      *pReg |= BLIT_COLOR_FORM_ARGB8888 | BLIT_TY_FULL_ALPHA_RANGE;
      break;

    case SURF_BGRA8888:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ARGB8888 big endian\n"));
      *pReg |= BLIT_COLOR_FORM_ARGB8888 | BLIT_TY_FULL_ALPHA_RANGE | BLIT_TY_BIG_ENDIAN;
      break;
    
    case SURF_RGB888:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RGB888\n"));
      *pReg |= BLIT_COLOR_FORM_RGB888;
      break;

#ifdef __TDT__	
     case SURF_BGR888:  
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RGB888 big endian\n"));  
      *pReg |= BLIT_COLOR_FORM_RGB888 | BLIT_TY_BIG_ENDIAN;  
      break; 
#endif

    case SURF_ARGB8565:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ARGB8565\n"));
      *pReg |= BLIT_COLOR_FORM_ARGB8565 | BLIT_TY_FULL_ALPHA_RANGE;
      break;

    case SURF_RGB565:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RGB565\n"));
      *pReg |= BLIT_COLOR_FORM_RGB565;
      break;

    case SURF_ARGB1555:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ARGB1555\n"));
      *pReg |= BLIT_COLOR_FORM_ARGB1555;
      break;

    case SURF_ARGB4444:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ARGB4444\n"));
      *pReg |= BLIT_COLOR_FORM_ARGB4444;
      break;

    case SURF_CLUT1:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_CLUT1\n"));
      *pReg |= BLIT_COLOR_FORM_CLUT1;
      break;

    case SURF_CLUT2:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_CLUT2\n"));
      *pReg |= BLIT_COLOR_FORM_CLUT2;
      break;

    case SURF_CLUT4:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_CLUT4\n"));
      *pReg |=BLIT_COLOR_FORM_CLUT4;
      break;
      
    case SURF_CLUT8:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_CLUT8\n"));
      *pReg |= BLIT_COLOR_FORM_CLUT8;
      break;

    case SURF_ACLUT44:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ACLUT44\n"));
      *pReg |= BLIT_COLOR_FORM_ACLUT44;
      break;
      
    case SURF_ACLUT88:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_ACLUT88\n"));
      *pReg |= BLIT_COLOR_FORM_ACLUT88 | BLIT_TY_FULL_ALPHA_RANGE;
      break;
    
    case SURF_ACRYCB8888:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_AYCBCR8888\n"));
      *pReg |= BLIT_COLOR_FORM_AYCBCR8888 | BLIT_TY_FULL_ALPHA_RANGE;
      break;
      
    case SURF_YCBCR420MB:
    case SURF_YCBCR422MB:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_YCBCR42XMB\n"));
      *pReg |= BLIT_COLOR_FORM_YCBCR42XMB;
      break;

    case SURF_CRYCB888:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_YCBCR888\n"));
      *pReg |= BLIT_COLOR_FORM_YCBCR888;
      break;

    case SURF_YCBCR422R:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_YCBCR422R\n"));
      *pReg |= BLIT_COLOR_FORM_YCBCR422R;
      break;
          
    case SURF_YUYV:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_YCBCR422R - big endian\n"));
      *pReg |= BLIT_COLOR_FORM_YCBCR422R | BLIT_TY_BIG_ENDIAN;
      break;
    case SURF_A8:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_A8\n"));
      *pReg |= BLIT_COLOR_FORM_A8 | BLIT_TY_FULL_ALPHA_RANGE;
      break;
    case SURF_A1:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_A1\n"));
      *pReg |= BLIT_COLOR_FORM_A1;
      break;  

    case SURF_YUV420:
    case SURF_YVU420:
    case SURF_YUV422P:
      DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_YUV444P\n"));
      *pReg |= BLIT_COLOR_FORM_YUV444P;
      break;

     /*
      * Intentional Assignment as opposed to |=
      * RLD Surface Types do _not_ have pitch/stride set
      */
     case SURF_RLD_BD:
       DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RLD_BD"));
       *pReg = BLIT_COLOR_FORM_RLD_BD;
       break;
     case SURF_RLD_H2:
       DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RLD_H2"));
       *pReg = BLIT_COLOR_FORM_RLD_H2;
       break;
     case SURF_RLD_H8:
       DEBUGF2(3, ("SetBufferType - BLIT_COLOR_FORM_RLD_H8"));
       *pReg = BLIT_COLOR_FORM_RLD_H8;
       break;

    default:
      return false;
  }
 
  return true;
}


void CSTmBlitter::SetKeyColour(const stm_blitter_surface_t &Surf, ULONG keyColour, ULONG* pReg) const
{
  DEBUGF2(2, (FENTRY ": keyColour = 0x%08lx\n", __PRETTY_FUNCTION__, keyColour));
  ULONG tmp;
  ULONG r,g,b;

  /*
   * Convert key colours to 32bit RGB required by the hardware. We do this
   * padding the missing LSBs with the MSBs to match the hardware expansion
   * mode we use for subbyte colour formats.
   */  
  switch (Surf.format)
  {
    case SURF_RGB565:
    case SURF_ARGB8565:
      r = ((keyColour & 0x0000F800) >> 13) | ((keyColour & 0x0000F800) >> 8);
      g = ((keyColour & 0x000007E0) >> 9)  | ((keyColour & 0x000007E0) >> 3);
      b = ((keyColour & 0x0000001F) >> 2)  | ((keyColour & 0x0000001F) << 3); 
      tmp = (r << 16) | (g << 8) | b;
      break;
    case SURF_ARGB1555:
      r = ((keyColour & 0x00007c00) >> 12) | ((keyColour & 0x00007c00) >> 7);
      g = ((keyColour & 0x000003E0) >> 7)  | ((keyColour & 0x000003E0) >> 2);
      b = ((keyColour & 0x0000001F) >> 2)  | ((keyColour & 0x0000001F) << 3); 
      tmp = (r << 16) | (g << 8) | b;
      break;
    case SURF_ARGB4444:
      r = ((keyColour & 0x00000F00) >> 8)  | ((keyColour & 0x00000F00) >> 4);
      g = ((keyColour & 0x000000F0) >> 4)  | (keyColour & 0x000000F0);
      b = (keyColour & 0x0000000F)         | ((keyColour & 0x0000000F) << 4); 
      tmp = (r << 16) | (g << 8) | b;
      break;  
    case SURF_RGB888:
    case SURF_ARGB8888:
    default:
      tmp = keyColour & 0x00FFFFFF;
      break;
  }

  /*
   * Preserve the alpha in the destination as it may be significant for 1-bit
   * alpha modes.
   */
  *pReg = (*pReg & 0xff000000) | tmp;

  DEBUGF2(2, (FEXIT ": key colour set to 0x%08lx.\n",__PRETTY_FUNCTION__,*pReg));
}


int CSTmBlitter::ChooseBlitter5x8FilterCoeffs(int src)
{  
  if(src <= 0)
    return -1;

  for(int i = 0; i < STM_NUM_5X8_FILTERS; i++)
  {
    if((src <= stm_blitter_5x8_filters[i].srcMax) && (src > stm_blitter_5x8_filters[i].srcMin))
    {
      return i;
    }
  }

  /* This is fine on BDisp based parts, I don't expect Gamma parts to have
     any issues with this either. */
  return N_ELEMENTS (stm_blitter_5x8_filters) - 1;
}


int CSTmBlitter::ChooseBlitter8x8FilterCoeffs(int src)
{  
  if(src <= 0)
    return -1;

  for(int i = 0; i < STM_NUM_8X8_FILTERS; i++)
  {
    if((src <= stm_blitter_8x8_filters[i].srcMax) && (src > stm_blitter_8x8_filters[i].srcMin))
    {
      return i;
    }
  }

  /* This is fine on BDisp based parts, I don't expect Gamma parts to have
     any issues with this either. */
  return N_ELEMENTS (stm_blitter_8x8_filters) - 1;
}

